-
Notifications
You must be signed in to change notification settings - Fork 990
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Permit transfers of wrapped ERC20 tokens between different addresses #329
Permit transfers of wrapped ERC20 tokens between different addresses #329
Conversation
f93e9ce
to
219daf5
Compare
219daf5
to
6d91b09
Compare
7365817
to
cd3be78
Compare
6d91b09
to
879c850
Compare
1e72843
to
b5f39d5
Compare
879c850
to
6018292
Compare
6018292
to
371c6ae
Compare
pls update wasm |
fd72d10
to
d27d6ed
Compare
pls update wasm |
use super::store; | ||
use crate::types::address::Address; | ||
|
||
pub(super) fn is_authorized( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to follow the idea here. Is that idea that since the users vps won't be triggered otherwise, we need to manually trigger them to see if they approve a multitoken transfer? If so, shouldn't we pass in the verifiers set here and insert the necessary vps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple of ways we could approach this and it'll probably be pretty involved (#432). At least for established accounts, we could force their VPs to be triggered to check the transaction, this is what vp_token
does - if we go that route, we should then update vp_user
to work with multitokens. For implicit accounts, this isn't an option, as we don't have implicit VPs (I think namadac transfer
does not do auth for transfers between implicit addresses either, will double check this and open an issue if so). For addresses of internal accounts, we can just reject any transfers made to/from them or have special hardcoded logic as appropriate.
When I was experimenting in https://github.com/anoma/anoma-wasm-multitoken, I was thinking we could instead have tx.data
signed by the sending account in such a way that the signature can be verified by the validity predicate. Then it would work like so:
- established accounts - we can look up the public key on chain of the Namada address which is sending the transfer, and use that to verify the signature
- implicit accounts - if we can't find a public key on chain, we must assume an implicit account (unless it's an internal account address which we can easily check) - in that case, we can "underive" the public key from the address
Ultimately the reader
, tx_data
and owner
arguments passed in must be all that is needed to verify the transfer is authorized by the sender.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implicit VPs are required for Namada launch, so I think triggering the necessary sender and receiver vps manually in this vp is the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implicit VPs are required for Namada launch, so I think triggering the necessary sender and receiver vps manually in this vp is the way to go.
Implicit VP issue - #8
I will scope out #432 further. There are some issues I think with the implicit VP approach in general, not directly related to the eth bridge, I can write up. For now then we can at least get parity with what works for normal tokens (i.e. proper authorization for transfers sent from an established address). Authorization for transfers sent from implicit addresses does not currently work even for normal token transfers using namadac transfer
, we will need to wait for #8 to be implemented
use crate::vm::WasmCacheAccess; | ||
|
||
/// Read pre/post storage | ||
pub(super) trait Reader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I've added these read_pre_value
and read_post_value
to the Ctx
type in the bridge pool PR, let's just use those instead (just steal them). They return a simpler type (Option<T>
instead of Result<Option<T>>
) so it is simpler to handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should share code functionality, though I'd rather we make an issue to update the Ctx
API in main
and then refactor everywhere at once. We shouldn't silently ignore errors though if they happen (i.e. we should use Result<Option<T>>
rather than Option<T>
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These methods are in eth_bridge_integration
now, so lets use them. But I agree, we shouldn't siliently ignore errors. It should be super fast to refactor the ctx methods to return the Result<Option<T>>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure I can refactor there in our codebase quickly, I will make an issue before merging this PR to update the Ctx
API in main
. I need to look closer at why it returns Result<Option<T>>
and not just Result<T>
as at a glance it looks like these read_pre
/read_post
methods error if a key isn't present in storage, I would have thought in that case it would have defaulted to None
and the errors would be reserved for things like e.g. rocksdb or OS-level errors.
1e0801e
to
f3dbc6b
Compare
pls update |
pls update wasm |
d261e5c
to
0d5e52d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let use the Ctx methods for reading/writing values instead of the reader trait. They should be refactored not to squash errors though. Afterwards, we can PR those changes towards main.
3529ecd
to
cc56e47
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm. just some random comments
@@ -117,11 +127,11 @@ where | |||
// but that will be a separate PR. | |||
let pending_key = get_pending_key(); | |||
let pending_pre: HashSet<PendingTransfer> = | |||
self.ctx.read_pre_value(&pending_key).ok_or(eyre!( | |||
(&self.ctx).read_pre_value(&pending_key)?.ok_or(eyre!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm why do we need the explicit borrow here, on ctx
? was the compiler (or clippy) complaining about something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's because the trait this method comes from is implemented only for &Ctx
and not Ctx
namada/shared/src/ledger/native_vp.rs
Line 337 in 635f68c
impl<'a, DB, H, CA> StorageReader for &Ctx<'a, DB, H, CA> |
If there is a nice way to implement for both Ctx
and &Ctx
without too much duplication, I'd like to add it (though not in this PR) for ergonomics. (This StorageReader
thing actually needs to be contributed back to main
or may even be able to be replaced by the new native storage traits coming in soon)
#[test] | ||
fn test_is_eth_bridge_key_returns_true_for_eth_bridge_subkey() { | ||
let key = Key::from(super::ADDRESS.to_db_key()) | ||
.push(&"arbitrary key segment".to_owned()) | ||
.expect("Could not set up test"); | ||
assert!(is_eth_bridge_key(&key)); | ||
} | ||
|
||
#[test] | ||
fn test_is_eth_bridge_key_returns_false_for_different_address() { | ||
let key = | ||
Key::from(address::testing::established_address_1().to_db_key()); | ||
assert!(!is_eth_bridge_key(&key)); | ||
} | ||
|
||
#[test] | ||
fn test_is_eth_bridge_key_returns_false_for_different_address_subkey() { | ||
let key = | ||
Key::from(address::testing::established_address_1().to_db_key()) | ||
.push(&"arbitrary key segment".to_owned()) | ||
.expect("Could not set up test"); | ||
assert!(!is_eth_bridge_key(&key)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good candidates for a proptest :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will have a go at this (though not in this PR)
cc56e47
to
954694d
Compare
Co-authored-by: Jacob Turner <[email protected]>
Co-authored-by: Jacob Turner <[email protected]>
Co-authored-by: Jacob Turner <[email protected]>
Co-authored-by: Jacob Turner <[email protected]>
954694d
to
635f68c
Compare
pls update wasm |
Closes #427
Currently, the EthBridge VP rejects any transactions which attempt to change keys in its space. This PR will change it to allow valid transfers of wrapped ERC20s between different users.
This PR does not include authorization of transfers by the user whose balance is decreasing - this will come in a later PR (#432). End-to-end tests for CI will also come in a separate PR (it will be based on the shell example in #394).